import xmlrpclib
from backend import Message
from SimpleXMLRPCServer import SimpleXMLRPCServer,SimpleXMLRPCRequestHandler
#~ from threading import *
#~ from etoffiutils2.list import head, tail
import time, sys, os

PERM_DENIED = 17
OK          = 43

class ReplySource:
	def noneAvailable(self):
		m = Message (self._x, '<null-targ>', 'msgserv noneavail')
		R = m.text()
		assert R != None
		return R
	def __init__(self, x):
		self._x = x

_counter=0
class AwxMessageServer:
	def registerClient (self, client_base_name):
		self.clients[client_base_name]=(client_base_name,)
		global _counter
		_counter+=3
		self._targets[client_base_name]=_counter
		return ['client registered', client_base_name, _counter]
			#, self.kk.address_string() ]

	#~ def targetFor (self, client_name):
		#~ T=self.clients[client_name]
		#~ return T

	def checkParam_From_To (self, main, src, to):
		return OK

	def reconstructMessage (self, aMsg_, source):
		print 31, source, aMsg_
		R = Message (source, aMsg_[1], aMsg_[0])
		R.payload = aMsg_[2]
		return R

	def queueMessage_From (self, aMsg_, source):
		aMsg = self.reconstructMessage (aMsg_, source)
		pr = self.checkParam_From_To (aMsg.main, source, aMsg.targ)
		if pr == PERM_DENIED:
			self.notifyDenied (source, aMsg)
		else:
			tr = self.targetForOrCreate (aMsg.targ)
			if not tr: return 700
			if tr.full():
				self.notifyWouldBlock(source, aMsg)
			else:
				tr.add (Message (aMsg, source))
				self.notifySuccess (source, aMsg)
		return 711
	
	def tt(self, source):
		x = ReplySource(source)
		return x
	
	def requestMessage (self, source_):
		source=self.tt(source_)
		tr = self.targetFor (source)
		if not tr:
			self.notifyNotAvailable (source)
		else:
			m = tr.first()
			tr.keepTail()
			self.notifyMessageAt(source, m)
		return 411

	def __init__(self):
		self._targets = {}
		self.quit = False
		self.clients  = {}

	def targetFor(self, source):
		if source in self._targets:
			return self._targets[source]
		#~ return self.notifyNotAvailable(source)
		raise 'no such source',source

	def targetForOrCreate(self, source):
		if not source in self._targets:
			self._targets[source] = []
		return self._targets[source]

	def notifyNotAvailable (self, source):
		a = source.noneAvailable()
		return a

	def notifyDenied(self, source, msg):
		source.denied(msg)
		return OK
	
	def notifyMessageAt(self, source, msg):
		self.notifyMessageAt(source, msg)
		return OK
	
	def notifySuccess(self, source, msg):
		source.success(msg)
		return OK

	def loop(self):
		while not self.quit:
			g = self.GetMessage()
			if g.main == 'quit':
				self.quit = True
			self.TranslateMessage(g)
			self.DispatchMessage(g)

	#~ def wndproc(msg, wparam, lparam):
		#~ return 1

class Math(AwxMessageServer):
	def _dispatch(self, method, params):
		print 100, '** dispatch', method, params
		R = self._xdispatch(method, params)
		assert R != None, "trying to marshal NoneType!!!"
		print 101, R
		return R
	
	def _xdispatch(self, method, params):
		print method, params
		if method == 'queueMessage_From':
			return apply(self.queueMessage_From, params)
		elif method == 'requestMessage':
			return apply (self.requestMessage, params)
		elif method == 'registerClient':
			return apply (self.registerClient, params)
		elif method == 'targetFor':
			return apply (self.targetFor, params)
		else:
			raise 'bad method'

class vv(SimpleXMLRPCRequestHandler):
	def do_POST(self):
		"""Handles the HTTP POST request.
	
		Attempts to interpret all HTTP POST requests as XML-RPC calls,
		which are forwarded to the _dispatch method for handling.
		"""
	
		try:
			# get arguments
			data = self.rfile.read(int(self.headers["content-length"]))
			params, method = xmlrpclib.loads(data)
	
			# generate response
			try:
				response = self._dispatch(method, params)
				# wrap response in a singleton tuple
				response = (response,)
			except:
				# report exception back to server
				import traceback
				traceback.print_exc()
				response = xmlrpclib.dumps(
					xmlrpclib.Fault(1, "%s:%s" % (sys.exc_type, sys.exc_value))
					)
			else:
				response = xmlrpclib.dumps(response, methodresponse=1)
		except Exception, e:
			print 600, e
			# internal error, report as HTTP server error
			self.send_response(500)
			self.end_headers()
		else:
			# got a valid XML RPC response
			self.send_response(200)
			self.send_header("Content-type", "text/xml")
			self.send_header("Content-length", str(len(response)))
			self.end_headers()
			self.wfile.write(response)
			
			# shut down the connection
			self.wfile.flush()
			self.connection.shutdown(1)

def main():
	server = SimpleXMLRPCServer(('localhost', 7557), requestHandler=vv)
	server.register_instance(Math())
	server.instance.kk = server 
	server.serve_forever()

main()

